#ifndef ROLE_H
#define ROLE_H

#include <uv.h> 
#include <string> 
#include <list>

enum role_type {
    role_none   = 0,
    role_server = 1,
    role_client = 2
};

class role {
public:
    role(uv_loop_t*);
    ~role() = default;
    role(const role&) = delete;
    role& operator=(const role&) = delete;
    static void on_connection_cb(uv_stream_t*, int);
    void send_message(std::string);
    int init(role_type);
    int create_client();
    int start_client_send();
    int start_client_send(int);

private:
    static void on_server_alloc(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf);
    static void on_client_alloc(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf);
    static void on_server_read(uv_stream_t* handle, ssize_t nread, const uv_buf_t* buf);
    static void on_client_read(uv_stream_t* handle, ssize_t nread, const uv_buf_t* buf);
    static void on_pipe_close(uv_handle_t* hanle);
    static void on_write(uv_write_t* req, int status);
    template<typename T>
    static void on_client_send_cb(T* handle);
    int create_server();

private:
    uv_loop_t* loop_;
    uv_pipe_t pipe_;
    uv_timer_t send_timer_;
    uv_idle_t send_idle_;

    role_type type_;
    bool is_connected_;
    void* buffer_;
    size_t total_;
    size_t index_;
    std::list<long> timestamp_;
    int send_num_;
};

#endif // ROLE_H 
